<script setup lang="ts">
import { onMounted } from "vue";
import Guacamole from "guacamole-common-js";
defineOptions({
  name: "SHTerminal"
});

const desktopObj = {
  client: undefined,
  layer: undefined,
  state: 0,
  sink: undefined
};
const getQueryParams = (url: string) => {
  const paramArr = url.slice(url.indexOf("?") + 1).split("&");
  const params = new Map();
  paramArr.map(param => {
    const [key, val] = param.split("=");
    params.set(key, decodeURIComponent(val));
  });
  return params;
};

onMounted(() => {
  wsHandshake();
  // // 监听窗口大小变化，执行窗口重绘操作
  // window.addEventListener('resize', onWindowResize)
  // window.onfocus = onWindowFocus
});

const wsHandshake = () => {
  const param = getQueryParams(window.location.href);
  const width = document.body.clientWidth - 1;
  const height = document.body.clientHeight;
  const params =
    "hostId=" +
    param.get("hostId") +
    "&authType=" +
    param.get("authType") +
    "&username=" +
    param.get("username") +
    "&password=" +
    param.get("password") +
    "&width=" +
    width +
    "&height=" +
    height +
    "&dpi=" +
    90;
  const websocketPath = "ws://" + "10.65.208.187:9000" + "/api/vap";
  const tunnel = new Guacamole.WebSocketTunnel(
    websocketPath + "/session/gua/sh"
  );
  console.log(websocketPath, tunnel);
  // 创建桌面客户端
  desktopObj.client = new Guacamole.Client(tunnel);
  // 解析自定义指令，这行代码必须放到  new Guacamole.Client(tunnel) 代码之后
  const _oninstruction = tunnel.oninstruction;
  tunnel.oninstruction = (opcode, parameters) => {
    onTunnelInstruction(opcode, parameters);
    if (_oninstruction) {
      _oninstruction(opcode, parameters);
    }
  };

  const display = document.getElementById("display");
  desktopObj.layer = desktopObj.client.getDisplay();
  const element = desktopObj.client.getDisplay().getElement();
  display.appendChild(element);
  desktopObj.client.connect(params);
  // 页面关闭时销毁客户端对象
  window.onunload = function () {
    desktopObj.client.disconnect();
  };

  // mouse
  const mouse = new Guacamole.Mouse(element);
  mouse.onmousedown =
    mouse.onmouseup =
    mouse.onmousemove =
      function (mouseState: any) {
        const ms = new Guacamole.Mouse.State(
          mouseState.x / desktopObj.layer.getScale(),
          mouseState.y / desktopObj.layer.getScale(),
          mouseState.left,
          mouseState.middle,
          mouseState.right,
          mouseState.up,
          mouseState.down
        );
        desktopObj.client.sendMouseState(ms);
      };
  // sink
  desktopObj.sink = new Guacamole.InputSink();
  display.appendChild(desktopObj.sink.getElement());
  desktopObj.sink.focus();

  // Keyboard
  const keyboard = new Guacamole.Keyboard(desktopObj.sink.getElement());
  keyboard.onkeydown = onKeyDown;
  keyboard.onkeyup = onKeyUp;
};

const onTunnelInstruction = (opcode: any, parameters: any) => {
  if (opcode == "hint") {
    ElNotification({
      title: decodeURI(parameters[0]),
      message: decodeURI(parameters[1]),
      type: parameters[2],
      duration: 0
    });
  }
  if (opcode == "disconnect") {
    console.log("连接销毁，画面关闭");
  }
  if (opcode == "error") {
    console.error("指令", opcode, "参数", parameters);
    desktopObj.client.disconnect();
  }
};
const onKeyUp = keySym => {
  desktopObj.client.sendKeyEvent(0, keySym);
};
const onKeyDown = keySym => {
  console.log(keySym);
  desktopObj.client.sendKeyEvent(1, keySym);
  if (keySym === 65288) {
    return false;
  }
};
</script>

<template>
  <div id="display" class="desktop-div" />
</template>

<style scoped>
.desktop-div {
  width: 100%;
  height: 100%;
}
</style>
